package com.hd123.rumba.util;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 填写startTime, count, progress后, 就可是用tohms(estimatedRemainTime())等方法
 * @author caili, 2006-11-10
 */
public class Progress {
  public static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  public static DecimalFormat df = new DecimalFormat("#00");
  private String catalog;
  private Date startTime;
  private Date endTime;
  private long total; // count in index
  private long count; // files to be checked
  private long progress; // files checked
  private Date updateTime; // progress last updated
  private List<String> errors = new ArrayList();

  public boolean equals(Object obj) {
    if (catalog == null)
      return false;
    if (obj == null)
      return false;
    if (obj instanceof Progress)
      return catalog.equals(((Progress) obj).getCatalog());
    return false;
  }

  public Date getUpdateTime() {
    return updateTime;
  }

  public void setUpdateTime(Date updateTime) {
    this.updateTime = updateTime;
  }

  public long getCount() {
    return count;
  }

  public void setCount(long count) {
    this.count = count;
  }

  public Date getEndTime() {
    return endTime;
  }

  public void setEndTime(Date endTime) {
    this.endTime = endTime;
  }

  public List<String> getErrors() {
    return errors;
  }

  public void setErrors(List<String> errors) {
    this.errors = errors;
  }

  public String getCatalog() {
    return catalog;
  }

  public void setCatalog(String path) {
    this.catalog = path;
  }

  public long getProgress() {
    return progress;
  }

  public void setProgress(long progress) {
    this.progress = progress;
    this.updateTime = new Date();
  }

  public Date getStartTime() {
    return startTime;
  }

  public void setStartTime(Date startTime) {
    this.startTime = startTime;
  }

  public long getTotal() {
    return total;
  }

  public void setTotal(long total) {
    this.total = total;
  }

  public long estimatedTotalTime() {
    if (progress == 0)
      return 0;
    return elapsedTime() * count / progress;
  }

  public long elapsedTime() {
    if (startTime == null || updateTime == null)
      return 0;
    return (updateTime.getTime() - startTime.getTime());
  }

  public long estimatedRemainTime() {
    if (progress == 0)
      return 0;
    return estimatedTotalTime() - elapsedTime();
  }

  public long percentage() {
    if (count == 0)
      return 0;
    return progress * 100 / count;
  }

  public static String tohms(long ms) {
    ms = ms / 1000;
    long h = ms / 3600;
    ms -= h * 3600;
    long m = ms / 60;
    ms -= m * 60;
    long s = ms;
    if (h == 0 && m == 0 && s == 0)
      return "";
    else
      return df.format(h) + ":" + df.format(m) + ":" + df.format(s);
  }

  public void error(String s) {
    errors.add(s);
  }

  public String toXmlString() {
    StringBuffer sb = new StringBuffer();
    sb.append("<IndexSummary>\n");
    sb.append("<catalog>" + catalog + "</catalog>\n");
    sb.append("<startTime>" + (startTime == null ? "" : sdf.format(startTime)) + "</startTime>\n");
    sb.append("<endTime>" + (endTime == null ? "" : sdf.format(endTime)) + "</endTime>\n");
    sb.append("<total>" + total + "</total>\n");
    sb.append("<count>" + count + "</count>\n");
    sb.append("<progress>" + progress + "</progress>\n");
    sb.append("<estimatedTotalTime>" + tohms(estimatedTotalTime()) + "</estimatedTotalTime>\n");
    sb.append("<estimatedRemainTime>" + tohms(estimatedRemainTime()) + "</estimatedRemainTime>\n");
    sb.append("<elapsedTime>" + tohms(elapsedTime()) + "</elapsedTime>\n");
    sb.append("<percentage>" + percentage() + "</percentage>\n");
    sb.append("<errors>\n");
    for (int i = 0; i < errors.size(); ++i) {
      sb.append("<error>" + errors.get(i) + "</error>\n");
    }
    sb.append("</errors>\n");
    sb.append("</IndexSummary>\n");
    return sb.toString();
  }

  public void assign(Progress s) {
    setCatalog(s.getCatalog());
    setStartTime(s.getStartTime());
    setEndTime(s.getEndTime());
    setTotal(s.getTotal());
    setCount(s.getCount());
    setProgress(s.getProgress());
    setUpdateTime(s.getUpdateTime());
    setErrors(s.getErrors());
  }

  public static class DProgress {
    private String catalog;
    private Date startTime;
    private Date endTime;
    private long total; // count in index
    private long count; // files to be checked
    private long progress; // files checked
    private Date updateTime;
    private String[] errors;

    public DProgress() {

    }

    public DProgress(Progress s) {
      catalog = s.catalog;
      startTime = s.startTime;
      endTime = s.endTime;
      total = s.total;
      count = s.count;
      progress = s.progress;
      updateTime = s.updateTime;
      errors = s.errors.toArray(new String[] {});
    }

    public Progress toIndexSummary() {
      Progress s = new Progress();
      s.catalog = catalog;
      s.startTime = startTime;
      s.endTime = endTime;
      s.total = total;
      s.count = count;
      s.progress = progress;
      s.updateTime = updateTime;
      if (errors != null)
        s.errors.addAll(Arrays.asList(errors));
      return s;
    }

    public Date getUpdateTime() {
      return updateTime;
    }

    public void setUpdateTime(Date updateTime) {
      this.updateTime = updateTime;
    }

    public long getCount() {
      return count;
    }

    public void setCount(long count) {
      this.count = count;
    }

    public Date getEndTime() {
      return endTime;
    }

    public void setEndTime(Date endTime) {
      this.endTime = endTime;
    }

    public String[] getErrors() {
      return errors;
    }

    public void setErrors(String[] errors) {
      this.errors = errors;
    }

    public String getCatalog() {
      return catalog;
    }

    public void setCatalog(String path) {
      this.catalog = path;
    }

    public long getProgress() {
      return progress;
    }

    public void setProgress(long progress) {
      this.progress = progress;
    }

    public Date getStartTime() {
      return startTime;
    }

    public void setStartTime(Date startTime) {
      this.startTime = startTime;
    }

    public long getTotal() {
      return total;
    }

    public void setTotal(long total) {
      this.total = total;
    }

  }

}
